/*
 *  Librarie de tipuri de date abstracte (TDA)
 
    Copyright (C) 2007  Catedra de Structuri de Date

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <stdlib.h>
#include <assert.h>
#include "btnode.h"

struct btnode_adt
{
	struct btnode_adt *parent;
	struct btnode_adt *sons[2];
	const void *data;
	int size;
	int height;
};

BTNode BTN_New(const void* data)
{
	BTNode newNode = (BTNode)malloc(sizeof(struct btnode_adt));
	newNode->sons[LEFT] = newNode->sons[RIGHT] = newNode->parent = NULL;
	newNode->data = data;
	newNode->size = 1;
	newNode->height = 1;
	return newNode;
}

void* BTN_GetData(BTNode node)
{
	assert(node);
	
	return (void*)node->data;
}

void BTN_SetData(BTNode node, const void* data)
{
	assert(node);
	
	node->data = data;
}

BTNode BTN_GetParent(BTNode node)
{
	assert(node);
	
	return node->parent;
}

BTNode BTN_GetSon(BTNode node, Direction dir)
{
	assert(node);
	
	return node->sons[dir];
}

void BTN_SetSon(BTNode node, Direction dir, BTNode newSon)
{
	assert(node);
	
	node->sons[dir] = newSon;
	
	if (newSon != NULL)
		newSon->parent = node;
}

void* BTN_Delete(BTNode node)
{
	void *data;
	assert(node);
	if (node->parent != NULL)
	{
		if (node->parent->sons[LEFT] == node)
			node->parent->sons[LEFT] = NULL;
		if (node->parent->sons[RIGHT] == node)
			node->parent->sons[RIGHT] = NULL;
	}
	if (node->sons[LEFT] != NULL)
		node->sons[LEFT]->parent = NULL;
	if (node->sons[RIGHT] != NULL)
		node->sons[RIGHT]->parent = NULL;
	data = (void*)node->data;
	free(node);
	return data;
}
